#pragma once
#include <stdint.h>
#define TLV_BUFFER_MAX_SIZE 4096
#define TLV_VALUE_MAX_SIZE (TLV_BUFFER_MAX_SIZE-sizeof(uint8_t)-sizeof(uint32_t))

#define    REQUEST_CMD_EXIT     0
#define    REQUEST_CMD_LOGIN    1
#define    REQUEST_CMD_CD       2
#define    REQUEST_CMD_PWD      3
#define    REQUEST_CMD_LS       4
#define    REQUEST_CMD_MKDIR    5
#define    REQUEST_CMD_RMDIR    6
#define    REQUEST_CMD_REMOVE   7
#define    REQUEST_CMD_PUTS     8
#define    REQUEST_CMD_GETS     9
#define    RESPONSE             10

typedef enum{
    TLV_E_VALUE_TO_LARGE,
    TLV_E_SEND_FAIL,
    TLV_E_CONNECT_IS_OVER,
    TLV_E_RECV_TYPE,
    TLV_E_RECV_LENGTH,
    TLV_E_RECV_VALUE,
    TLV_E_CALLBACK
}TLV_ERROR_TYPE;

typedef struct tlv_s{
    uint8_t buffer[TLV_BUFFER_MAX_SIZE];
    TLV_ERROR_TYPE error_type;
}tlv_t;

typedef void*(*callback_ptr_t)(tlv_t *tlv,int sockfd,uint8_t,uint32_t,const uint8_t*,void *);
int tlv_send(tlv_t *tlv,int sockfd,uint8_t type,uint32_t length,const uint8_t *value);
int tlv_recv(tlv_t *tlv,int sockfd,uint8_t *type,uint32_t *length);
int tlv_request(tlv_t *tlv,int sockfd,uint8_t type,uint32_t length,const uint8_t *value,callback_ptr_t callback,void *args);
int tlv_response(tlv_t *tlv,int sockfd,uint32_t length,const uint8_t *value);
int tlv_listen(tlv_t *tlv,int sockfd,callback_ptr_t callback,void *args);
const char *tlv_error_str(tlv_t *tlv);
